import { Repository } from 'typeorm';
import { AppDataSource } from '../config/database';
import { User } from '../entities/User';
import { Payment } from '../entities/Payment';
import { Subscription } from '../entities/Subscription';
import { stripe } from '../config/stripe';
import Stripe from 'stripe';

export class PaymentService {
  private getUserRepository(): Repository<User> {
    if (!AppDataSource.isInitialized) {
      throw new Error('数据库连接未初始化。请确保数据库已正确配置并连接。');
    }
    return AppDataSource.getRepository(User);
  }

  private getPaymentRepository(): Repository<Payment> {
    if (!AppDataSource.isInitialized) {
      throw new Error('数据库连接未初始化。请确保数据库已正确配置并连接。');
    }
    return AppDataSource.getRepository(Payment);
  }

  private getSubscriptionRepository(): Repository<Subscription> {
    if (!AppDataSource.isInitialized) {
      throw new Error('数据库连接未初始化。请确保数据库已正确配置并连接。');
    }
    return AppDataSource.getRepository(Subscription);
  }

  /**
   * 创建或获取Stripe客户
   */
  async createOrGetStripeCustomer(userId: string): Promise<Stripe.Customer> {
    const userRepository = this.getUserRepository();
    const user = await userRepository.findOne({ where: { id: parseInt(userId) } });
    if (!user) {
      throw new Error('用户不存在');
    }

    // 如果用户已有Stripe客户ID，直接返回
    if (user.stripeCustomerId) {
      try {
        const customer = await stripe.customers.retrieve(user.stripeCustomerId);
        if (!customer.deleted) {
          return customer as Stripe.Customer;
        }
      } catch (error) {
        console.error('获取Stripe客户失败:', error);
      }
    }

    // 创建新的Stripe客户
    const customer = await stripe.customers.create({
      email: user.email,
      name: user.firstName && user.lastName ? `${user.firstName} ${user.lastName}` : user.username,
      metadata: {
        userId: user.id.toString(),
      },
    });

    // 更新用户的Stripe客户ID
    await userRepository.update(user.id, { stripeCustomerId: customer.id });

    return customer;
  }

  /**
   * 创建支付意图
   */
  async createPaymentIntent(params: {
    userId: string;
    amount: number;
    currency?: string;
    description?: string;
    metadata?: Record<string, any>;
    automaticPaymentMethods?: boolean;
    allowRedirects?: boolean;
    paymentMethodTypes?: string[];
  }): Promise<{ paymentIntent: Stripe.PaymentIntent; clientSecret: string }> {
    const { 
      userId, 
      amount, 
      currency = 'usd', 
      description, 
      metadata, 
      automaticPaymentMethods = true,
      allowRedirects = true,
      paymentMethodTypes
    } = params;

    // 创建或获取Stripe客户
    const customer = await this.createOrGetStripeCustomer(userId);

    // 创建支付意图配置
    const paymentIntentConfig: Stripe.PaymentIntentCreateParams = {
      amount: Math.round(amount * 100), // Stripe使用最小货币单位
      currency,
      customer: customer.id,
      description,
      metadata: {
        userId,
        allowRedirects: allowRedirects.toString(),
        ...metadata,
      },
    };

    // 配置支付方式 - 支持所有可用的支付方式
    if (automaticPaymentMethods) {
      // 启用自动支付方式，支持所有Stripe支持的支付方式
      paymentIntentConfig.automatic_payment_methods = {
        enabled: true,
        allow_redirects: allowRedirects ? 'always' : 'never'
      };
    } else if (paymentMethodTypes && paymentMethodTypes.length > 0) {
      // 手动指定支付方式类型
      paymentIntentConfig.payment_method_types = paymentMethodTypes;
    } else {
      // 默认支持常用的支付方式
      paymentIntentConfig.payment_method_types = [
        'card',
        'alipay',
        'wechat_pay',
        'klarna',
        'afterpay_clearpay',
        'apple_pay',
        'google_pay',
        'link',
        'paypal'
      ];
    }

    // 创建支付意图
    const paymentIntent = await stripe.paymentIntents.create(paymentIntentConfig);

    // 保存支付记录到数据库
    const paymentRepository = this.getPaymentRepository();
    const payment = paymentRepository.create({
      stripePaymentIntentId: paymentIntent.id,
      stripeCustomerId: customer.id,
      amount,
      currency,
      status: 'pending',
      description,
      metadata: {
        allowRedirects,
        ...metadata,
      },
      userId,
    });
    await paymentRepository.save(payment);

    return {
      paymentIntent,
      clientSecret: paymentIntent.client_secret!,
    };
  }

  /**
   * 确认支付
   */
  async confirmPayment(paymentIntentId: string): Promise<Stripe.PaymentIntent> {
    const paymentIntent = await stripe.paymentIntents.confirm(paymentIntentId);
    
    // 更新数据库中的支付状态
    await this.updatePaymentStatus(paymentIntentId, paymentIntent.status as any);
    
    return paymentIntent;
  }

  /**
   * 使用支付方式确认支付（后端处理，不推荐用于生产环境）
   */
  async confirmPaymentWithMethod(
    paymentIntentId: string,
    paymentMethodData: {
      type: 'card';
      card: {
        number: string;
        exp_month: number;
        exp_year: number;
        cvc: string;
      };
      billing_details?: {
        name?: string;
        email?: string;
        address?: any;
      };
    }
  ): Promise<Stripe.PaymentIntent> {
    try {
      // 1. 创建支付方式
      const paymentMethod = await stripe.paymentMethods.create({
        type: paymentMethodData.type,
        card: paymentMethodData.card,
        billing_details: paymentMethodData.billing_details,
      });

      // 2. 确认支付并附加支付方式
      const paymentIntent = await stripe.paymentIntents.confirm(paymentIntentId, {
        payment_method: paymentMethod.id,
      });

      // 3. 更新数据库状态
      await this.updatePaymentStatus(paymentIntentId, paymentIntent.status as any);

      return paymentIntent;
    } catch (error: any) {
      console.error('后端确认支付失败:', error);
      throw new Error(`支付确认失败: ${error.message}`);
    }
  }

  /**
   * 获取支付意图
   */
  async getPaymentIntent(paymentIntentId: string): Promise<Stripe.PaymentIntent> {
    return await stripe.paymentIntents.retrieve(paymentIntentId);
  }

  /**
   * 取消支付
   */
  async cancelPayment(paymentIntentId: string): Promise<Stripe.PaymentIntent> {
    const paymentIntent = await stripe.paymentIntents.cancel(paymentIntentId);
    
    // 更新数据库中的支付状态
    await this.updatePaymentStatus(paymentIntentId, 'canceled');
    
    return paymentIntent;
  }

  /**
   * 更新支付状态
   */
  async updatePaymentStatus(
    paymentIntentId: string, 
    status: 'pending' | 'processing' | 'succeeded' | 'failed' | 'canceled' | 'requires_action'
  ): Promise<void> {
    const paymentRepository = this.getPaymentRepository();
    await paymentRepository.update(
      { stripePaymentIntentId: paymentIntentId },
      { status }
    );
  }

  /**
   * 获取用户的支付历史
   */
  async getUserPayments(userId: string, limit = 10, offset = 0): Promise<Payment[]> {
    const paymentRepository = this.getPaymentRepository();
    return await paymentRepository.find({
      where: { userId },
      order: { createdAt: 'DESC' },
      take: limit,
      skip: offset,
    });
  }

  /**
   * 创建订阅
   */
  async createSubscription(params: {
    userId: string;
    priceId: string;
    trialPeriodDays?: number;
    metadata?: Record<string, any>;
  }): Promise<Stripe.Subscription> {
    const { userId, priceId, trialPeriodDays, metadata } = params;

    // 创建或获取Stripe客户
    const customer = await this.createOrGetStripeCustomer(userId);

    // 创建订阅
    const subscription = await stripe.subscriptions.create({
      customer: customer.id,
      items: [{ price: priceId }],
      trial_period_days: trialPeriodDays,
      metadata: {
        userId,
        ...metadata,
      },
    });

    // 保存订阅记录到数据库
    const subscriptionRepository = this.getSubscriptionRepository();
    
    // 处理时间字段，确保有默认值
    const now = new Date();
    const currentPeriodStart = (subscription as any).current_period_start ? 
      new Date((subscription as any).current_period_start * 1000) : now;
    const currentPeriodEnd = (subscription as any).current_period_end ? 
      new Date((subscription as any).current_period_end * 1000) : new Date(now.getTime() + 30 * 24 * 60 * 60 * 1000); // 30天后
    
    const subscriptionEntity = subscriptionRepository.create({
      stripeSubscriptionId: subscription.id,
      stripeCustomerId: customer.id,
      stripePriceId: priceId,
      status: subscription.status as any,
      currentPeriodStart: currentPeriodStart,
      currentPeriodEnd: currentPeriodEnd,
      trialStart: (subscription as any).trial_start ? new Date((subscription as any).trial_start * 1000) : undefined,
      trialEnd: (subscription as any).trial_end ? new Date((subscription as any).trial_end * 1000) : undefined,
      cancelAtPeriodEnd: (subscription as any).cancel_at_period_end || false,
      metadata,
      userId,
    });
    await subscriptionRepository.save(subscriptionEntity);

    return subscription;
  }

  /**
   * 取消订阅
   */
  async cancelSubscription(subscriptionId: string, cancelAtPeriodEnd = true): Promise<Stripe.Subscription> {
    let subscription: Stripe.Subscription;

    if (cancelAtPeriodEnd) {
      subscription = await stripe.subscriptions.update(subscriptionId, {
        cancel_at_period_end: true,
      });
    } else {
      subscription = await stripe.subscriptions.cancel(subscriptionId);
    }

    // 更新数据库中的订阅状态
    await this.getSubscriptionRepository().update(
      { stripeSubscriptionId: subscriptionId },
      {
        status: subscription.status as any,
        cancelAtPeriodEnd: subscription.cancel_at_period_end,
        canceledAt: subscription.canceled_at ? new Date(subscription.canceled_at * 1000) : undefined,
      }
    );

    return subscription;
  }

  /**
   * 获取用户的订阅
   */
  async getUserSubscriptions(userId: string): Promise<Subscription[]> {
    return await this.getSubscriptionRepository().find({
      where: { userId },
      order: { createdAt: 'DESC' },
    });
  }

  /**
   * 处理Webhook事件
   */
  async handleWebhookEvent(event: Stripe.Event): Promise<void> {
    switch (event.type) {
      case 'payment_intent.succeeded':
        await this.handlePaymentIntentSucceeded(event.data.object as Stripe.PaymentIntent);
        break;
      case 'payment_intent.payment_failed':
        await this.handlePaymentIntentFailed(event.data.object as Stripe.PaymentIntent);
        break;
      case 'invoice.payment_succeeded':
        await this.handleInvoicePaymentSucceeded(event.data.object as Stripe.Invoice);
        break;
      case 'customer.subscription.updated':
        await this.handleSubscriptionUpdated(event.data.object as Stripe.Subscription);
        break;
      case 'customer.subscription.deleted':
        await this.handleSubscriptionDeleted(event.data.object as Stripe.Subscription);
        break;
      default:
        console.log(`未处理的事件类型: ${event.type}`);
    }
  }

  private async handlePaymentIntentSucceeded(paymentIntent: Stripe.PaymentIntent): Promise<void> {
    await this.updatePaymentStatus(paymentIntent.id, 'succeeded');
    console.log(`支付成功: ${paymentIntent.id}`);
  }

  private async handlePaymentIntentFailed(paymentIntent: Stripe.PaymentIntent): Promise<void> {
    await this.updatePaymentStatus(paymentIntent.id, 'failed');
    console.log(`支付失败: ${paymentIntent.id}`);
  }

  private async handleInvoicePaymentSucceeded(invoice: Stripe.Invoice): Promise<void> {
    if ((invoice as any).subscription) {
      console.log('订阅发票支付成功');
    }
  }

  private async handleSubscriptionUpdated(subscription: Stripe.Subscription): Promise<void> {
    await this.getSubscriptionRepository().update(
      { stripeSubscriptionId: subscription.id },
      {
        status: subscription.status as any,
        currentPeriodStart: new Date((subscription as any).current_period_start * 1000),
        currentPeriodEnd: new Date((subscription as any).current_period_end * 1000),
        cancelAtPeriodEnd: (subscription as any).cancel_at_period_end,
        canceledAt: (subscription as any).canceled_at ? new Date((subscription as any).canceled_at * 1000) : undefined,
      }
    );
    console.log(`订阅更新: ${subscription.id}`);
  }

  private async handleSubscriptionDeleted(subscription: Stripe.Subscription): Promise<void> {
    await this.getSubscriptionRepository().update(
      { stripeSubscriptionId: subscription.id },
      {
        status: 'canceled',
        canceledAt: new Date(),
      }
    );
    console.log(`订阅删除: ${subscription.id}`);
  }
}